home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / dev / sun4.md / devSCSI0.c < prev    next >
C/C++ Source or Header  |  1990-10-11  |  33KB  |  1,046 lines

  1. /* 
  2.  * devSCSI0.c --
  3.  *
  4.  *    Driver routines specific to the original Sun Host Adaptor.
  5.  *    This lives either on the Multibus or the VME.  It does
  6.  *    not support dis-connect/connect.
  7.  *     This information is derived from Sun's "Manual for Sun SCSI
  8.  *    Programmers", which details the layout of the this implementation
  9.  *    of the Host Adaptor, the device that interfaces to the SCSI Bus.
  10.  *
  11.  * Copyright 1986 Regents of the University of California
  12.  * Permission to use, copy, modify, and distribute this
  13.  * software and its documentation for any purpose and without
  14.  * fee is hereby granted, provided that the above copyright
  15.  * notice appear in all copies.  The University of California
  16.  * makes no representations about the suitability of this
  17.  * software for any purpose.  It is provided "as is" without
  18.  * express or implied warranty.
  19.  */
  20.  
  21. #ifndef lint
  22. static char rcsid[] = "$Header: /sprite/src/kernel/dev/sun3.md/RCS/devSCSI0.c,v 9.2 90/10/11 15:42:55 mendel Exp $ SPRITE (Berkeley)";
  23. #endif not lint
  24.  
  25.  
  26. #include "sprite.h"
  27. #include "mach.h"
  28. #include "scsi0.h"
  29. #include "dev.h"
  30. #include "devInt.h"
  31. #include "scsi.h"
  32. #include "scsiHBA.h"
  33. #include "scsiDevice.h"
  34. #include "devMultibus.h"
  35. #include "sync.h"
  36. #include "stdio.h"
  37. #include "stdlib.h"
  38. #include "bstring.h"
  39. #include "string.h"
  40.  
  41. /*
  42.  * The device registers for the original Sun SCSI Host Adaptor.
  43.  * Through these registers the SCSI bus is controlled.  There are the
  44.  * usual status and control bits, and there are also registers through
  45.  * which command blocks and status blocks are transmitted.  This format
  46.  * is defined on Page 10. of Sun's SCSI Programmers' Manual.
  47.  */
  48. typedef struct CtrlRegs {
  49.     unsigned char data;        /* Data register.  Contains the ID of the
  50.                  * SCSI "target", or controller, for the 
  51.                  * SELECT phase. Also, leftover odd bytes
  52.                  * are left here after a read. */
  53.     unsigned char pad1;        /* The other half of the data register which
  54.                  * is never used by us */
  55.     unsigned char commandStatus;/* Command and status blocks are passed
  56.                  * in and out through this */
  57.     unsigned char pad2;        /* The other half of the commandStatus register
  58.                  * which never contains useful information */
  59.     unsigned short control;    /* The SCSI interface control register.
  60.                  * Bits are defined below */
  61.     unsigned short pad3;
  62.     unsigned int dmaAddress;    /* Target address for DMA */
  63.     short     dmaCount;    /* Number of bytes for DMA.  Initialize this
  64.                  * this to minus the byte count minus 1 more,
  65.                  * and the device increments to -1. If this
  66.                  * is 0 or 1 after a transfer then there was
  67.                  * a DMA overrun. */
  68.     unsigned char pad4;
  69.     unsigned char intrVector;    /* For VME, Index into autovector */
  70. } CtrlRegs;
  71.  
  72. /*
  73.  * Control bits in the SCSI Host Interface control register.
  74.  *
  75.  *    SCSI_PARITY_ERROR There was a parity error on the SCSI bus.
  76.  *    SCSI_BUS_ERROR    There was a bus error on the SCSI bus.
  77.  *    SCSI_ODD_LENGTH An odd byte is left over in the data register after
  78.  *            a read or write.
  79.  *    SCSI_INTERRUPT_REQUEST bit checked by polling routine.  If a command
  80.  *            block is sent and the SCSI_INTERRUPT_ENABLE bit is
  81.  *            NOT set, then the appropriate thing to do is to
  82.  *            wait around (poll) until this bit is set.
  83.  *    SCSI_REQUEST    Set by controller to start byte passing handshake.
  84.  *    SCSI_MESSAGE    Set by a controller during message phase.
  85.  *    SCSI_COMMAND    Set during the command, status, and messages phase.
  86.  *    SCSI_INPUT    If set means data (or commandStatus) set by device.
  87.  *    SCSI_PARITY    Used to test the parity checking hardware.
  88.  *    SCSI_BUSY    Set by controller after it has been selected.
  89.  *  The following bits can be set by the CPU.
  90.  *    SCSI_SELECT    Set by the host when it want to select a controller.
  91.  *    SCSI_RESET    Set by the host when it want to reset the SCSI bus.
  92.  *    SCSI_PARITY_ENABLE    Enable parity checking on transfer
  93.  *    SCSI_WORD_MODE        Send 2 bytes at a time
  94.  *    SCSI_DMA_ENABLE        Do DMA, always used.
  95.  *    SCSI_INTERRUPT_ENABLE    Interrupt upon completion.
  96.  */
  97. #define SCSI_PARITY_ERROR        0x8000
  98. #define SCSI_BUS_ERROR            0x4000
  99. #define SCSI_ODD_LENGTH            0x2000
  100. #define SCSI_INTERRUPT_REQUEST        0x1000
  101. #define SCSI_REQUEST            0x0800
  102. #define SCSI_MESSAGE            0x0400
  103. #define SCSI_COMMAND            0x0200
  104. #define SCSI_INPUT            0x0100
  105. #define SCSI_PARITY            0x0080
  106. #define SCSI_BUSY            0x0040
  107. #define SCSI_SELECT            0x0020
  108. #define SCSI_RESET            0x0010
  109. #define SCSI_PARITY_ENABLE        0x0008
  110. #define SCSI_WORD_MODE            0x0004
  111. #define SCSI_DMA_ENABLE            0x0002
  112. #define SCSI_INTERRUPT_ENABLE        0x0001
  113.  
  114. /* Forward declaration. */
  115. typedef struct Controller Controller;
  116.  
  117. /*
  118.  * Device - The data structure containing information about a device. One of
  119.  * these structure is kept for each attached device. Note that is structure
  120.  * is casted into a ScsiDevice and returned to higher level software.
  121.  * This implies that the ScsiDevice must be the first field in this
  122.  * structure.
  123.  */
  124.  
  125. typedef struct Device {
  126.     ScsiDevice handle;    /* Scsi Device handle. This is the only part
  127.              * of this structure visible to higher 
  128.              * level software. MUST BE FIRST FIELD IN STRUCTURE.
  129.              */
  130.     int    targetID;    /* SCSI Target ID of this device. Note that
  131.              * the LUN is store in the device handle.
  132.              */
  133.     Controller *ctrlPtr;    /* Controller to which device is attached. */
  134.            /*
  135.             * The following part of this structure is 
  136.             * used to handle SCSI commands that return 
  137.             * CHECK status. To handle the REQUEST SENSE
  138.             * command we must: 1) Save the state of the current
  139.             * command into the "struct FrozenCommand". 2) Submit
  140.             * a request sense command formatted in SenseCmd
  141.             * to the device.
  142.             */
  143.     struct FrozenCommand {               
  144.     ScsiCmd    *scsiCmdPtr;      /* The frozen command. */
  145.     unsigned char statusByte; /* It's SCSI status byte, Will always have
  146.                    * the check bit set.  */
  147.     int amountTransferred;    /* Number of bytes transferred by this 
  148.                    * command.  */
  149.     } frozen;    
  150.     char senseBuffer[DEV_MAX_SENSE_BYTES]; /* Data buffer for request sense */
  151.     ScsiCmd        SenseCmd;         /* Request sense command buffer. */
  152. } Device;
  153.  
  154. /*
  155.  * Controller - The Data structure describing a sun SCSI0 controller. One
  156.  * of these structures exists for each active SCSI0 HBA on the system. Each
  157.  * controller may have from zero to 56 (7 targets each with 8 logical units)
  158.  * devices attached to it. 
  159.  */
  160. struct Controller {
  161.     volatile CtrlRegs *regsPtr;    /* Pointer to the registers
  162.                                     of this controller. */
  163.     int        dmaState;    /* DMA state for this controller, defined below. */
  164.     char    *name;    /* String for error message for this controller.  */
  165.     DevCtrlQueues devQueues;    /* Device queues for devices attached to this
  166.                  * controller.     */
  167.     Sync_Semaphore mutex; /* Lock protecting controller's data structures. */
  168.     Device     *devPtr;       /* Current active command. */
  169.     ScsiCmd   *scsiCmdPtr; /* Current active command. */
  170.     Address   dmaBuffer;  /* dma buffer allocated for request. */
  171.     Device  *devicePtr[8][8]; /* Pointers to the device
  172.                                * attached to the
  173.                    * controller index by [targetID][LUN].
  174.                    * NIL if device not attached yet. Zero if
  175.                    * device conflicts with HBA address.  */
  176.  
  177. };
  178.  
  179. /* 
  180.  * SCSI_WAIT_LENGTH - the number of microseconds that the host waits for
  181.  *    various control lines to be set on the SCSI bus.  The largest wait
  182.  *    time is when a controller is being selected.  This delay is
  183.  *    called the Bus Abort delay and is about 250 milliseconds.
  184.  */
  185. #define SCSI_WAIT_LENGTH        250000
  186.  
  187. /*
  188.  * Possible values for the dmaState state field of a controller.
  189.  *
  190.  * DMA_RECEIVE  - data is being received from the device, such as on
  191.  *    a read, inquiry, or request sense.
  192.  * DMA_SEND     - data is being send to the device, such as on a write.
  193.  * DMA_INACTIVE - no data needs to be transferred.
  194.  */
  195.  
  196. #define DMA_RECEIVE 0
  197. #define    DMA_SEND 1
  198. #define    DMA_INACTIVE 2
  199. /*
  200.  * Test, mark, and unmark the controller as busy.
  201.  */
  202. #define    IS_CTRL_BUSY(ctrlPtr)    ((ctrlPtr)->scsiCmdPtr != (ScsiCmd *) NIL)
  203. #define    SET_CTRL_BUSY(ctrlPtr,scsiCmdPtr) \
  204.         ((ctrlPtr)->scsiCmdPtr = (scsiCmdPtr))
  205. #define    SET_CTRL_FREE(ctrlPtr)    ((ctrlPtr)->scsiCmdPtr = (ScsiCmd *) NIL)
  206.  
  207. /*
  208.  * MAX_SCSI0_CTRLS - Maximum number of SCSI0 controllers attached to the
  209.  *             system. We set this to the maximum number of VME slots
  210.  *             in any Sun2 system currently available.
  211.  */
  212. #define    MAX_SCSI0_CTRLS    4
  213. static Controller *Controllers[MAX_SCSI0_CTRLS];
  214. /*
  215.  * Highest number controller we have probed for.
  216.  */
  217. static int numSCSI0Controllers = 0;
  218.  
  219. int devSCSI0Debug = 0;
  220.  
  221. static void RequestDone _ARGS_ ((Device *devPtr, ScsiCmd *scsiCmdPtr,
  222.     ReturnStatus status, unsigned int scsiStatusByte, int amountTransferred));
  223. static ReturnStatus Wait _ARGS_ ((Controller *ctrlPtr,
  224.     int condition, Boolean reset));
  225. static int SpecialSenseProc _ARGS_ ((void));
  226.  
  227.  
  228. /*
  229.  *----------------------------------------------------------------------
  230.  *
  231.  * Probe --
  232.  *
  233.  *    Probe memory for the old-style VME SCSI interface.  We rely
  234.  *    on the fact that this occupies 4K of address space. 
  235.  *
  236.  * Results:
  237.  *    TRUE if the host adaptor was found.
  238.  *
  239.  * Side effects:
  240.  *    None.
  241.  *
  242.  *----------------------------------------------------------------------
  243.  */
  244. static Boolean
  245. Probe(address)
  246.     int address;            /* Alledged controller address */
  247. {
  248.     ReturnStatus    status;
  249.     register volatile CtrlRegs *regsPtr = (CtrlRegs *)address;
  250.     short value;
  251.  
  252.     /*
  253.      * Touch the device. If it exists it occupies 4K.
  254.      */
  255.     value = 0x4BCC;
  256.     status = Mach_Probe(sizeof(regsPtr->dmaCount), (char *) &value,
  257.             (char *) &(regsPtr->dmaCount));
  258.     if (status == SUCCESS) {
  259.     value = 0x5BCC;
  260.     status = Mach_Probe(sizeof(regsPtr->dmaCount),(char *) &value,
  261.               ((char *) &(regsPtr->dmaCount)) + 0x800);
  262.     }
  263.     return(status == SUCCESS);
  264. }
  265.  
  266.  
  267. /*
  268.  *----------------------------------------------------------------------
  269.  *
  270.  * Reset --
  271.  *
  272.  *    Reset a SCSI bus controlled by the orignial Sun Host Adaptor.
  273.  *
  274.  * Results:
  275.  *    None.
  276.  *
  277.  * Side effects:
  278.  *    Reset the controller.
  279.  *
  280.  *----------------------------------------------------------------------
  281.  */
  282. static void
  283. Reset(ctrlPtr)
  284.     Controller *ctrlPtr;
  285. {
  286.     volatile CtrlRegs *regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  287.  
  288.     regsPtr->control = SCSI_RESET;
  289.     MACH_DELAY(100);
  290.     regsPtr->control = 0;
  291. }
  292.  
  293. /*
  294.  *----------------------------------------------------------------------
  295.  *
  296.  * SendCommand --
  297.  *
  298.  *      Send a command to a controller on the old-style SCSI Host Adaptor
  299.  *      indicated by devPtr.  
  300.  *
  301.  *    Note: the ID of the controller is never placed on the bus
  302.  *    (contrary to standard protocol, but necessary for the early Sun
  303.  *    SCSI interface).
  304.  *
  305.  * Results:
  306.  *    An error code.
  307.  *
  308.  * Side effects:
  309.  *    Those of the command (Read, write etc.)
  310.  *
  311.  *----------------------------------------------------------------------
  312.  */
  313. static ReturnStatus
  314. SendCommand(devPtr, scsiCmdPtr)
  315.     Device    *devPtr;        /* Device to sent to. */
  316.     ScsiCmd    *scsiCmdPtr;        /* Command to send. */
  317. {
  318.     register ReturnStatus status;
  319.     register volatile CtrlRegs *regsPtr;/* Host Adaptor registers */
  320.     char *charPtr;            /* Used to put the control block
  321.                      * into the commandStatus register */
  322.     int bits = 0;            /* variable bits to OR into control */
  323.     int targetID;            /* Id of the SCSI device to select */
  324.     int size;                /* Number of bytes to transfer */
  325.     Address addr;            /* Kernel address of transfer */
  326.     Controller    *ctrlPtr;        /* HBA of device. */
  327.     int    i;
  328.  
  329.     /*
  330.      * Set current active device and command for this controller.
  331.      */
  332.     ctrlPtr = devPtr->ctrlPtr;
  333.     SET_CTRL_BUSY(ctrlPtr,scsiCmdPtr);
  334.     ctrlPtr->dmaBuffer = (Address) NIL;
  335.     ctrlPtr->devPtr = devPtr;
  336.     size = scsiCmdPtr->bufferLen;
  337.     addr = scsiCmdPtr->buffer;
  338.     targetID = devPtr->targetID;
  339.     regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  340.     if (size == 0) {
  341.     ctrlPtr->dmaState = DMA_INACTIVE;
  342.     } else {
  343.     ctrlPtr->dmaState = (scsiCmdPtr->dataToDevice) ? DMA_SEND :
  344.                              DMA_RECEIVE;
  345.     }
  346.    /*
  347.      * Check against a continuously busy bus.  This stupid condition would
  348.      * fool the code below that tries to select a device.
  349.      */
  350.     for (i=0 ; i < SCSI_WAIT_LENGTH ; i++) {
  351.     if ((regsPtr->control & SCSI_BUSY) == 0) {
  352.         break;
  353.     } else {
  354.         MACH_DELAY(10);
  355.     }
  356.     }
  357.     if (i == SCSI_WAIT_LENGTH) {
  358.     Reset(ctrlPtr);
  359.     printf("Warning: %s SCSI bus stuck busy\n", ctrlPtr->name);
  360.     return(FAILURE);
  361.     }
  362.     /*
  363.      * Select the device.  Sun's SCSI Programmer's Manual recommends
  364.      * resetting the SCSI_WORD_MODE bit so that the byte packing hardware
  365.      * is reset and the data byte that has the target ID gets transfered
  366.      * correctly.  After this, the target's ID is put in the data register,
  367.      * the SELECT bit is set, and we wait until the device responds
  368.      * by setting the BUSY bit.  The ID bit of the host adaptor is not
  369.      * put in the data word because of problems with Sun's Host Adaptor.
  370.      */
  371.     regsPtr->control = 0;
  372.     regsPtr->data = (1 << targetID);
  373.     regsPtr->control = SCSI_SELECT;
  374.     status = Wait(ctrlPtr, SCSI_BUSY, FALSE);
  375.     if (status != SUCCESS) {
  376.     regsPtr->data = 0;
  377.     regsPtr->control = 0;
  378.         printf("Warning: %s: can't select device at %s\n", 
  379.                  ctrlPtr->name, devPtr->handle.locationName);
  380.     return(status);
  381.     }
  382.     /*
  383.      * Set up the interface's registers for the transfer.  The DMA address
  384.      * is relative to the multibus memory so the kernel's base address
  385.      * for multibus memory is subtracted from 'addr'. The host adaptor
  386.      * increments the dmaCount register until it reaches -1, hence the
  387.      * funny initialization. See page 4 of Sun's SCSI Prog. Manual.
  388.      */
  389.     if (ctrlPtr->dmaState != DMA_INACTIVE) {
  390.     ctrlPtr->dmaBuffer = addr = VmMach_DMAAlloc(size,scsiCmdPtr->buffer);
  391.     }
  392.     if (addr == (Address) NIL) {
  393.     panic("%s can't allocate DMA buffer of %d bytes\n", 
  394.             devPtr->handle.locationName, size);
  395.     }
  396.     regsPtr->dmaAddress = (int)(addr - VMMACH_DMA_START_ADDR);
  397.     regsPtr->dmaCount = -size - 1;
  398.     bits = SCSI_WORD_MODE | SCSI_DMA_ENABLE | SCSI_INTERRUPT_ENABLE;
  399.     regsPtr->control = bits;
  400.  
  401.     /*
  402.      * Stuff the control block through the commandStatus register.
  403.      * The handshake on the SCSI bus is visible here:  we have to
  404.      * wait for the Request line on the SCSI bus to be raised before
  405.      * we can send the next command byte to the controller.  All commands
  406.      * are of "group 0" which means they are 6 bytes long.
  407.      */
  408.     charPtr = scsiCmdPtr->commandBlock;
  409.     for (i=0 ; i < scsiCmdPtr->commandBlockLen ; i++) {
  410.     status = Wait(ctrlPtr, SCSI_REQUEST, TRUE);
  411.     if (status != SUCCESS) {
  412.         printf("Warning: %s couldn't send command block byte %d\n",
  413.                  ctrlPtr->name, i);
  414.         return(status);
  415.     }
  416.     /*
  417.      * The device keeps the Control/Data line set while it
  418.      * is accepting control block bytes.
  419.      */
  420.     if ((regsPtr->control & SCSI_COMMAND) == 0) {
  421.         Reset(ctrlPtr);
  422.         printf("Warning: %s: device %s dropped command line\n",
  423.                 ctrlPtr->name, devPtr->handle.locationName);
  424.         return(DEV_HANDSHAKE_ERROR);
  425.     }
  426.         regsPtr->commandStatus = *charPtr;
  427.     charPtr++;
  428.     }
  429.     return(SUCCESS);
  430. }
  431.  
  432. /*
  433.  *----------------------------------------------------------------------
  434.  *
  435.  * GetStatusByte --
  436.  *
  437.  *    Complete an SCSI command by getting the status bytes from
  438.  *    the device and waiting for the ``command complete''
  439.  *    message that follows the status bytes.  If the command has
  440.  *    additional ``sense data'' then this routine issues the
  441.  *    SCSI_REQUEST_SENSE command to get the sense data.
  442.  *
  443.  * Results:
  444.  *    An error code if the status didn't come through or it
  445.  *    indicated an error.
  446.  *
  447.  * Side effects:
  448.  *    None.
  449.  *
  450.  *----------------------------------------------------------------------
  451.  */
  452. static ReturnStatus
  453. GetStatusByte(ctrlPtr, statusBytePtr)
  454.     Controller *ctrlPtr;
  455.     unsigned char *statusBytePtr;
  456. {
  457.     register ReturnStatus status;
  458.     register volatile CtrlRegs *regsPtr;
  459.     short message;
  460.     char statusByte;
  461.     int numStatusBytes = 0;
  462.  
  463.     regsPtr = ctrlPtr->regsPtr;
  464.     *statusBytePtr = 0;
  465.     for (;;) {
  466.     /*
  467.      * Could probably wait either on the INTERUPT_REQUEST bit or the
  468.      * REQUEST bit.  Reading the byte out of the commandStatus
  469.      * register acknowledges the REQUEST and clears these bits.  Here
  470.      * we grab bytes until the MESSAGE bit indicates that all the
  471.      * status bytes have been received and that the byte in the
  472.      * commandStatus register is the message byte.
  473.      */
  474.     status = Wait(ctrlPtr, SCSI_REQUEST, TRUE);
  475.     if (status != SUCCESS) {
  476.         printf("Warning: %s: wait error after %d status bytes\n",
  477.                  ctrlPtr->name, numStatusBytes);
  478.         break;
  479.     }
  480.     if (regsPtr->control & SCSI_MESSAGE) {
  481.         message = regsPtr->commandStatus & 0xff;
  482.         if (message != SCSI_COMMAND_COMPLETE) {
  483.         printf("Warning %s: Unexpected message 0x%x\n",
  484.                      ctrlPtr->name, message);
  485.         }
  486.         break;
  487.     } else {
  488.         /*
  489.          * This is another status byte.  Place the first status
  490.          * bytes into the status block.
  491.          */
  492.         statusByte = regsPtr->commandStatus;
  493.         if (numStatusBytes < 1) {
  494.         *statusBytePtr = statusByte;
  495.         }
  496.         numStatusBytes++;
  497.     }
  498.     }
  499.     return(status);
  500. }
  501.  
  502. /*
  503.  *----------------------------------------------------------------------
  504.  *
  505.  * Wait --
  506.  *
  507.  *    Wait for a condition in the SCSI controller.
  508.  *
  509.  * Results:
  510.  *    SUCCESS if the condition occurred before a threashold time limit,
  511.  *    DEV_TIMEOUT otherwise.
  512.  *
  513.  * Side effects:
  514.  *    This resets the SCSI bus if the reset parameter is true and
  515.  *    the condition bits are not set by the controller before timeout..
  516.  *
  517.  *----------------------------------------------------------------------
  518.  */
  519. static ReturnStatus
  520. Wait(ctrlPtr, condition, reset)
  521.     Controller *ctrlPtr;
  522.     int condition;
  523.     Boolean reset;
  524. {
  525.     volatile CtrlRegs *regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  526.     register int i;
  527.     ReturnStatus status = DEV_TIMEOUT;
  528.     register int control = 0;
  529.  
  530.     for (i=0 ; i < SCSI_WAIT_LENGTH ; i++) {
  531.     control = regsPtr->control;
  532.     if (devSCSI0Debug && i < 5) {
  533.         printf("%d/%x ", i, control);
  534.     }
  535.     if (control & condition) {
  536.         return(SUCCESS);
  537.     }
  538.     if (control & SCSI_BUS_ERROR) {
  539.         printf("Warning: %s : SCSI bus error\n",ctrlPtr->name);
  540.         status = DEV_DMA_FAULT;
  541.         break;
  542.     } else if (control & SCSI_PARITY_ERROR) {
  543.         printf("Warning: %s: parity error\n",ctrlPtr->name);
  544.         status = DEV_DMA_FAULT;
  545.         break;
  546.     }
  547.     MACH_DELAY(10);
  548.     }
  549.     if (devSCSI0Debug) {
  550.     printf("DevSCSI0Wait: timed out, control = %x.\n", control);
  551.     }
  552.     if (reset) {
  553.     Reset(ctrlPtr);
  554.     }
  555.     return(status);
  556. }
  557.  
  558. /*
  559.  *----------------------------------------------------------------------
  560.  *
  561.  * entryAvailProc --
  562.  *
  563.  *    Act upon an entry becomming available in the queue for this
  564.  *    controller. This routine is the Dev_Queue callback function that
  565.  *    is called whenever work becomes available for this controller. 
  566.  *    If the controller is not already busy we dequeue and start the
  567.  *    request.
  568.  *    NOTE: This routine is also called from DevSCSI0Intr to start the
  569.  *    next request after the previously one finishes.
  570.  *
  571.  * Results:
  572.  *    None.
  573.  *
  574.  * Side effects:
  575.  *    Request may be dequeue and submitted to the device. Request callback
  576.  *    function may be called.
  577.  *
  578.  *----------------------------------------------------------------------
  579.  */
  580.  
  581. static Boolean
  582. entryAvailProc(clientData, newRequestPtr) 
  583.    ClientData    clientData;    /* Really the Device this request ready. */
  584.    List_Links *newRequestPtr;    /* The new SCSI request. */
  585. {
  586.     register Device *devPtr; 
  587.     register Controller *ctrlPtr;
  588.     register ScsiCmd    *scsiCmdPtr;
  589.     ReturnStatus    status;
  590.  
  591.     devPtr = (Device *) clientData;
  592.     ctrlPtr = devPtr->ctrlPtr;
  593.     /*
  594.      * If we are busy (have an active request) just return. Otherwise 
  595.      * start the request.
  596.      */
  597.  
  598.     if (IS_CTRL_BUSY(ctrlPtr)) { 
  599.     return FALSE;
  600.     }
  601. again:
  602.     scsiCmdPtr = (ScsiCmd *) newRequestPtr;
  603.     devPtr = (Device *) clientData;
  604.     status = SendCommand( devPtr, scsiCmdPtr);
  605.     /*    
  606.      * If the command couldn't be started do the callback function.
  607.      */
  608.     if (status != SUCCESS) {
  609.      RequestDone(devPtr,scsiCmdPtr,status,0,0);
  610.     }
  611.     if (!IS_CTRL_BUSY(ctrlPtr)) { 
  612.         newRequestPtr = Dev_QueueGetNextFromSet(ctrlPtr->devQueues,
  613.                 DEV_QUEUE_ANY_QUEUE_MASK,&clientData);
  614.     if (newRequestPtr != (List_Links *) NIL) { 
  615.         goto again;
  616.     }
  617.     }
  618.     return TRUE;
  619.  
  620. }   
  621.  
  622.  
  623. /*
  624.  *----------------------------------------------------------------------
  625.  *
  626.  *  SpecialSenseProc --
  627.  *
  628.  *    Special function used for HBA generated REQUEST SENSE. A SCSI
  629.  *    command request with this function as a call back proc will
  630.  *    be processed by routine RequestDone as a result of a 
  631.  *    REQUEST SENSE. This routine is never called.
  632.  *
  633.  * Results:
  634.  *    None.
  635.  *
  636.  * Side effects:
  637.  *    None.
  638.  *
  639.  *----------------------------------------------------------------------
  640.  */
  641.  
  642. static int
  643. SpecialSenseProc()
  644. {
  645.     return 0;
  646. }
  647.  
  648.  
  649. /*
  650.  *----------------------------------------------------------------------
  651.  *
  652.  * RequestDone --
  653.  *
  654.  *    Process a request that has finished. Unless a SCSI check condition
  655.  *    bit is present in the status returned, the request call back
  656.  *    function is called.  If check condition is set we fire off a
  657.  *    SCSI REQUEST SENSE to get the error sense bytes from the device.
  658.  *
  659.  * Results:
  660.  *    None.
  661.  *
  662.  * Side effects:
  663.  *    The call back function may be called.
  664.  *
  665.  *----------------------------------------------------------------------
  666.  */
  667.  
  668. static void
  669. RequestDone(devPtr,scsiCmdPtr,status,scsiStatusByte,amountTransferred)
  670.     Device    *devPtr;    /* Device for request. */
  671.     ScsiCmd    *scsiCmdPtr;    /* Request that finished. */
  672.     ReturnStatus status;    /* Status returned. */
  673.     unsigned int scsiStatusByte;    /* SCSI Status Byte. */
  674.     int        amountTransferred; /* Amount transferred by command. */
  675. {
  676.     ReturnStatus    senseStatus;
  677.     Controller            *ctrlPtr = devPtr->ctrlPtr;
  678.  
  679.  
  680.     if (devSCSI0Debug > 3) {
  681.     printf("RequestDone for %s status 0x%x scsistatus 0x%x count %d\n",
  682.         devPtr->handle.locationName, status,scsiStatusByte,
  683.         amountTransferred);
  684.     }
  685.     if (ctrlPtr->dmaState != DMA_INACTIVE) {
  686.     VmMach_DMAFree(scsiCmdPtr->bufferLen,ctrlPtr->dmaBuffer);
  687.     ctrlPtr->dmaState = DMA_INACTIVE;
  688.     }
  689.     /*
  690.      * First check to see if this is the reponse of a HBA generated 
  691.      * REQUEST SENSE command.  If this is the case, we can process
  692.      * the callback of the frozen command for this device and
  693.      * allow the flow of command to the device to be resummed.
  694.      */
  695.     if (scsiCmdPtr->doneProc == SpecialSenseProc) {
  696.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  697.     (devPtr->frozen.scsiCmdPtr->doneProc)(devPtr->frozen.scsiCmdPtr, 
  698.             SUCCESS,
  699.             devPtr->frozen.statusByte, 
  700.             devPtr->frozen.amountTransferred,
  701.             amountTransferred,
  702.             devPtr->senseBuffer);
  703.      MASTER_LOCK(&(ctrlPtr->mutex));
  704.      SET_CTRL_FREE(ctrlPtr);
  705.      return;
  706.     }
  707.     /*
  708.      * This must be a outside request finishing. If the request 
  709.      * suffered an error or the HBA or the scsi status byte
  710.      * says there is no error sense present, we can do the
  711.      * callback and free the controller.
  712.      */
  713.     if ((status != SUCCESS) || !SCSI_CHECK_STATUS(scsiStatusByte)) {
  714.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  715.     (scsiCmdPtr->doneProc)(scsiCmdPtr, status, scsiStatusByte,
  716.                    amountTransferred, 0, (char *) 0);
  717.      MASTER_LOCK(&(ctrlPtr->mutex));
  718.      SET_CTRL_FREE(ctrlPtr);
  719.      return;
  720.    } 
  721.    /*
  722.     * If we got here than the SCSI command came back from the device
  723.     * with the CHECK bit set in the status byte.
  724.     * Need to perform a REQUEST SENSE. Move the current request 
  725.     * into the frozen state and issue a REQUEST SENSE. 
  726.     */
  727.    devPtr->frozen.scsiCmdPtr = scsiCmdPtr;
  728.    devPtr->frozen.statusByte = scsiStatusByte;
  729.    devPtr->frozen.amountTransferred = amountTransferred;
  730.    DevScsiSenseCmd((ScsiDevice *)devPtr, DEV_MAX_SENSE_BYTES, 
  731.            devPtr->senseBuffer, &(devPtr->SenseCmd));
  732.    devPtr->SenseCmd.doneProc = SpecialSenseProc,
  733.    senseStatus = SendCommand(devPtr, &(devPtr->SenseCmd));
  734.    /*
  735.     * If we got an HBA error on the REQUEST SENSE we end the outside 
  736.     * command with the SUCCESS status but zero sense bytes returned.
  737.     */
  738.    if (senseStatus != SUCCESS) {
  739.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  740.     (scsiCmdPtr->doneProc)(scsiCmdPtr, status, scsiStatusByte,
  741.                    amountTransferred, 0, (char *) 0);
  742.     MASTER_LOCK(&(ctrlPtr->mutex));
  743.     SET_CTRL_FREE(ctrlPtr);
  744.    }
  745.  
  746. }
  747.  
  748. /*
  749.  *----------------------------------------------------------------------
  750.  *
  751.  * DevSCSI0Intr --
  752.  *
  753.  *    Handle interrupts from the SCSI controller.  This has to poll
  754.  *    through the possible SCSI controllers to find the one generating
  755.  *    the interrupt.  The usual action is to wake up whoever is waiting
  756.  *    for I/O to complete.  This may also start up another transaction
  757.  *    with the controller if there are things in its queue.
  758.  *
  759.  * Results:
  760.  *    TRUE if the SCSI controller was responsible for the interrupt
  761.  *    and this routine handled it.
  762.  *
  763.  * Side effects:
  764.  *    Usually a process is notified that an I/O has completed.
  765.  *
  766.  *----------------------------------------------------------------------
  767.  */
  768. /* ARGSUSED */ 
  769. Boolean
  770. DevSCSI0Intr(clientDataArg)
  771.     ClientData    clientDataArg;
  772. {
  773.     register Controller *ctrlPtr;
  774.     List_Links *newRequestPtr;
  775.     Device    *devPtr;
  776.     volatile CtrlRegs *regsPtr;
  777.     int        residual;
  778.     ReturnStatus    status;
  779.     unsigned char statusByte;
  780.     ClientData    clientData;
  781.  
  782.     ctrlPtr = (Controller *) clientDataArg;
  783.     regsPtr = ctrlPtr->regsPtr;
  784.     devPtr = ctrlPtr->devPtr;
  785.     MASTER_LOCK(&(ctrlPtr->mutex));
  786.     if (regsPtr->control & SCSI_INTERRUPT_REQUEST) {
  787.     if (regsPtr->control & SCSI_BUS_ERROR) {
  788.         if (regsPtr->dmaCount >= 0) {
  789.         /*
  790.          * A DMA overrun.  Unlikely with a disk but could
  791.          * happen while reading a large tape block.  Consider
  792.          * the I/O complete with no residual bytes
  793.          * un-transferred.
  794.          */
  795.         residual = 0;
  796.         } else {
  797.         /*
  798.          * A real Bus Error.  Complete the I/O but flag an error.
  799.          * The residual is computed because the Bus Error could
  800.          * have occurred after a number of sectors.
  801.          */
  802.         residual = -regsPtr->dmaCount -1;
  803.         }
  804.         /*
  805.          * The board needs to be reset to clear the Bus Error
  806.          * condition so no status bytes are grabbed.
  807.          */
  808.         Reset(ctrlPtr);
  809.         status = DEV_DMA_FAULT;
  810.         RequestDone(devPtr, ctrlPtr->scsiCmdPtr, status, 0,
  811.             ctrlPtr->scsiCmdPtr->bufferLen - residual);
  812.         if (!IS_CTRL_BUSY(ctrlPtr)) {
  813.         newRequestPtr = Dev_QueueGetNextFromSet(ctrlPtr->devQueues,
  814.                 DEV_QUEUE_ANY_QUEUE_MASK,&clientData);
  815.         if (newRequestPtr != (List_Links *) NIL) { 
  816.             (void) entryAvailProc(clientData,newRequestPtr);
  817.         }
  818.         }
  819.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  820.         return(TRUE);
  821.     } else {
  822.         /*
  823.          * Normal command completion.  Compute the residual,
  824.          * the number of bytes not transferred, check for
  825.          * odd transfer sizes, and finally get the completion
  826.          * status from the device.
  827.          */
  828.         if (!IS_CTRL_BUSY(ctrlPtr)) {
  829.         printf("Warning: Spurious interrupt from SCSI0\n");
  830.         Reset(ctrlPtr);
  831.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  832.         return(TRUE);
  833.         }
  834.         residual = -regsPtr->dmaCount -1;
  835.         if (regsPtr->control & SCSI_ODD_LENGTH) {
  836.         /*
  837.          * On a read the last odd byte is left in the data
  838.          * register.  On both reads and writes the number
  839.          * of bytes transferred as determined from dmaCount
  840.          * is off by one.  See Page 8 of Sun's SCSI
  841.          * Programmers' Manual.
  842.          */
  843.         if (!ctrlPtr->scsiCmdPtr->dataToDevice) {
  844.           *(volatile char *)(DEV_MULTIBUS_BASE + regsPtr->dmaAddress) =
  845.             regsPtr->data;
  846.             residual--;
  847.         } else {
  848.             residual++;
  849.         }
  850.         }
  851.         status = GetStatusByte(ctrlPtr,&statusByte);
  852.         RequestDone(devPtr, ctrlPtr->scsiCmdPtr, status, 
  853.             statusByte,
  854.             ctrlPtr->scsiCmdPtr->bufferLen - residual);
  855.         if (!IS_CTRL_BUSY(ctrlPtr)) {
  856.         newRequestPtr = Dev_QueueGetNextFromSet(ctrlPtr->devQueues,
  857.                 DEV_QUEUE_ANY_QUEUE_MASK,&clientData);
  858.         if (newRequestPtr != (List_Links *) NIL) { 
  859.             (void) entryAvailProc(clientData,newRequestPtr);
  860.         }
  861.         }
  862.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  863.         return(TRUE);
  864.     }
  865.     }
  866.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  867.     return (FALSE);
  868. }
  869.  
  870. /*
  871.  *----------------------------------------------------------------------
  872.  *
  873.  * ReleaseProc --
  874.  *
  875.  *    Device release proc for controller.
  876.  *
  877.  * Results:
  878.  *    None.
  879.  *
  880.  * Side effects:
  881.  *    None.
  882.  *
  883.  *----------------------------------------------------------------------
  884.  */
  885. /*ARGSUSED*/
  886. static ReturnStatus
  887. ReleaseProc(scsiDevicePtr)
  888.     ScsiDevice    *scsiDevicePtr;
  889. {
  890.     return SUCCESS;
  891. }
  892.  
  893.  
  894. /*
  895.  *----------------------------------------------------------------------
  896.  *
  897.  * DevSCSI0Init --
  898.  *
  899.  *    Check for the existant of the Sun SCSI0 HBA controller. If it
  900.  *    exists allocate data stuctures for it.
  901.  *
  902.  * Results:
  903.  *    TRUE if the controller exists, FALSE otherwise.
  904.  *
  905.  * Side effects:
  906.  *    Memory may be allocated.
  907.  *
  908.  *----------------------------------------------------------------------
  909.  */
  910. ClientData
  911. DevSCSI0Init(ctrlLocPtr)
  912.     DevConfigController    *ctrlLocPtr;    /* Controller location. */
  913. {
  914.     int    ctrlNum;
  915.     Boolean    found;
  916.     Controller *ctrlPtr;
  917.     int    i,j;
  918.  
  919.     /*
  920.      * See if the controller is there. 
  921.      */
  922.     ctrlNum = ctrlLocPtr->controllerID;
  923.     found =  Probe(ctrlLocPtr->address);
  924.     if (!found) {
  925.     return DEV_NO_CONTROLLER;
  926.     }
  927.     /*
  928.      * It's there. Allocate and fill in the Controller structure.
  929.      */
  930.     if (ctrlNum+1 > numSCSI0Controllers) {
  931.     numSCSI0Controllers = ctrlNum+1;
  932.     }
  933.     Controllers[ctrlNum] = ctrlPtr = (Controller *) malloc(sizeof(Controller));
  934.     bzero((char *) ctrlPtr, sizeof(Controller));
  935.     ctrlPtr->regsPtr = (volatile CtrlRegs *) (ctrlLocPtr->address);
  936.     ctrlPtr->regsPtr->intrVector = ctrlLocPtr->vectorNumber;
  937.     ctrlPtr->name = ctrlLocPtr->name;
  938.     Sync_SemInitDynamic(&(ctrlPtr->mutex),ctrlPtr->name);
  939.     /* 
  940.      * Initialized the name, device queue header, and the master lock.
  941.      * The controller comes up with no devices active and no devices
  942.      * attached.  Reserved the devices associated with the 
  943.      * targetID of the controller (7).
  944.      */
  945.     ctrlPtr->devQueues = Dev_CtrlQueuesCreate(&(ctrlPtr->mutex),entryAvailProc);
  946.     for (i = 0; i < 8; i++) {
  947.     for (j = 0; j < 8; j++) {
  948.         ctrlPtr->devicePtr[i][j] = (i == 7) ? (Device *) 0 : (Device *) NIL;
  949.     }
  950.     }
  951.     ctrlPtr->scsiCmdPtr = (ScsiCmd *) NIL;
  952.     Controllers[ctrlNum] = ctrlPtr;
  953.     Reset(ctrlPtr);
  954.     return (ClientData) ctrlPtr;
  955. }
  956.  
  957.  
  958. /*
  959.  *----------------------------------------------------------------------
  960.  *
  961.  * DevSCSI0ttachDevice --
  962.  *
  963.  *    Attach a SCSI device using the Sun SCSI0 HBA. 
  964.  *
  965.  * Results:
  966.  *    None.
  967.  *
  968.  * Side effects:
  969.  *    None.
  970.  *
  971.  *----------------------------------------------------------------------
  972.  */
  973.  
  974. ScsiDevice   *
  975. DevSCSI0AttachDevice(devicePtr, insertProc)
  976.     Fs_Device    *devicePtr;     /* Device to attach. */
  977.     void    (*insertProc) _ARGS_ ((List_Links *elementPtr,
  978.                                        List_Links *elementListHdrPtr));
  979.                                  /* Queue insert procedure. */
  980. {
  981.     Device *devPtr;
  982.     Controller    *ctrlPtr;
  983.     char   tmpBuffer[512];
  984.     int       length;
  985.     int       ctrlNum;
  986.     int       targetID, lun;
  987.  
  988.     /*
  989.      * First find the SCSI0 controller this device is on.
  990.      */
  991.     ctrlNum = SCSI_HBA_NUMBER(devicePtr);
  992.     if ((ctrlNum > MAX_SCSI0_CTRLS) ||
  993.     (Controllers[ctrlNum] == (Controller *) 0)) { 
  994.     return (ScsiDevice  *) NIL;
  995.     } 
  996.     ctrlPtr = Controllers[ctrlNum];
  997.     targetID = SCSI_TARGET_ID(devicePtr);
  998.     lun = SCSI_LUN(devicePtr);
  999.     /*
  1000.      * Allocate a device structure for the device and fill in the
  1001.      * handle part. This must be created before we grap the MASTER_LOCK.
  1002.      */
  1003.     devPtr = (Device *) malloc(sizeof(Device)); 
  1004.     bzero((char *) devPtr, sizeof(Device));
  1005.     devPtr->handle.devQueue = Dev_QueueCreate(ctrlPtr->devQueues,
  1006.                 1, insertProc, (ClientData) devPtr);
  1007.     devPtr->handle.locationName = "Unknown";
  1008.     devPtr->handle.LUN = lun;
  1009.     devPtr->handle.releaseProc = ReleaseProc;
  1010.     devPtr->handle.maxTransferSize = 63*1024;
  1011.     /*
  1012.      * See if the device is already present.
  1013.      */
  1014.     MASTER_LOCK(&(ctrlPtr->mutex));
  1015.     /*
  1016.      * A device pointer of zero means that targetID/LUN 
  1017.      * conflicts with that of the HBA. A NIL means the
  1018.      * device hasn't been attached yet.
  1019.      */
  1020.     if (ctrlPtr->devicePtr[targetID][lun] == (Device *) 0) {
  1021.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  1022.     (void) Dev_QueueDestroy(devPtr->handle.devQueue);
  1023.     free((char *) devPtr);
  1024.     return (ScsiDevice *) NIL;
  1025.     }
  1026.     if (ctrlPtr->devicePtr[targetID][lun] != (Device *) NIL) {
  1027.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  1028.     (void) Dev_QueueDestroy(devPtr->handle.devQueue);
  1029.     free((char *) devPtr);
  1030.     return (ScsiDevice *) (ctrlPtr->devicePtr[targetID][lun]);
  1031.     }
  1032.  
  1033.     ctrlPtr->devicePtr[targetID][lun] = devPtr;
  1034.     devPtr->targetID = targetID;
  1035.     devPtr->ctrlPtr = ctrlPtr;
  1036.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  1037.  
  1038.     (void) sprintf(tmpBuffer, "%s#%d Target %d LUN %d", ctrlPtr->name, ctrlNum,
  1039.             devPtr->targetID, devPtr->handle.LUN);
  1040.     length = strlen(tmpBuffer);
  1041.     devPtr->handle.locationName = (char *) strcpy(malloc(length+1),tmpBuffer);
  1042.  
  1043.     return (ScsiDevice *) devPtr;
  1044. }
  1045.  
  1046.